package za.org.jcicada.genss.sensor.impl;

/**
 * SensorSubjectProxy.java
 *
 * @author Simon Cross
 *
 * Created on February 6, 2009, 10:50
 */

import java.net.URI;
import java.util.Set;

import za.org.jcicada.comms.IConnector;
import za.org.jcicada.comms.impl.MessageListenerBase;
import za.org.jcicada.comms.impl.ProxyBase;
import za.org.jcicada.genss.sensor.ISamplingStrategy;
import za.org.jcicada.genss.sensor.ISensorObserver;
import za.org.jcicada.genss.sensor.ISensorSubject;
import za.org.jcicada.genss.sensor.SensorURN;
import za.org.jcicada.genss.sensor.messages.AttachRequest;
import za.org.jcicada.genss.sensor.messages.DetachRequest;
import za.org.jcicada.genss.sensor.messages.SensorSetRequest;
import za.org.jcicada.genss.sensor.messages.SetSamplingStrategyRequest;

/**
 * ISensorSubject implementation that proxies requests through to
 * a remote sensor subject.
 */
public class SensorSubjectProxy extends ProxyBase<ISensorObserver> implements ISensorSubject {

    /**
     * Create a SensorSubjectProxy.
     *
     * @param connector IConnector object for creating connections to the remote subject.
     */
    public SensorSubjectProxy(IConnector connector) {
        super(connector);
    }
    
    /**
     * Create a SensorSubjectProxy.
     * 
     * @param locationURI address of the acceptor
     */
    public SensorSubjectProxy(URI locationURI) {
        super(locationURI);
    }

    @Override
    protected MessageListenerBase createReceiver(ISensorObserver client) {
        return new Receiver(client);
    }

    // ISensorSubject methods

    /**
     * Send AttachRequest.
     */
    public void requestAttach(ISensorObserver observer, Set<SensorURN> sensorURNs) {
        sendMessage(observer, new AttachRequest(sensorURNs));
    }

    /**
     * Send DetachRequest.
     */
    public void requestDetach(ISensorObserver observer, Set<SensorURN> sensorURNs) {
        sendMessage(observer, new DetachRequest(sensorURNs));
    }
    
    /**
     * Send SensorSetRequest.
     */
    public void requestSensorSet(ISensorObserver observer) {
        sendMessage(observer, new SensorSetRequest());
    }

    /**
     * Send SetSamplingStrategyRequest.
     */
    public void requestSetSamplingStrategy(ISensorObserver observer, ISamplingStrategy strategy) {
        sendMessage(observer, new SetSamplingStrategyRequest(strategy));
    }
    
    /**
     * Implementation of IMessageListener that dispatches messages to an ISensorObserver.
     */
    public class Receiver extends MessageListenerBase {

        /**
         * Handle to callback object for messages from the subject to the observer.
         */
        ISensorObserver observer;

        public Receiver(ISensorObserver observer) {
            this.observer = observer;
        }

        public void onClose() throws Exception {
            observer.informDisconnect();
        }

        // dispatch methods

        /**
         * Dispatch AttachReply.
         */
        public void sensorAttachReply(za.org.jcicada.genss.sensor.messages.AttachReply msg) {
            observer.replyAttach(msg.getResult(), msg.getSensorURNs());
        }

        /**
         * Dispatch DetachReply.
         */
        public void sensorDetachReply(za.org.jcicada.genss.sensor.messages.DetachReply msg) {
            observer.replyDetach(msg.getResult(), msg.getSensorURNs());
        }

        /**
         * Dispatch SensorSetReply.
         */
        public void sensorSensorSetReply(za.org.jcicada.genss.sensor.messages.SensorSetReply msg) {
            observer.replySensorSet(msg.getResult(), msg.getNumSensors());
        }

        /**
         * Dispatch SetSamplingStrategyReply.
         */
        public void sensorSetSamplingStrategyReply(za.org.jcicada.genss.sensor.messages.SetSamplingStrategyReply msg) {
            observer.replySetSamplingStrategy(msg.getResult());
        }

        /**
         * Dispatch UpdateSensorInform.
         */
        public void sensorUpdateSensorInform(za.org.jcicada.genss.sensor.messages.UpdateSensorInform msg) {
            observer.informSensor(msg.getSensorURN(), msg.getValue());
        }
        
        public void sensorUpdateSensorStatusInform(za.org.jcicada.genss.sensor.messages.UpdateSensorStatusInform msg) {
        	observer.informSensorStatus(msg.getSensorURN(), msg.getStatusValue());
        }

        /**
         * Dispatch UpdateSensorTypeInform.
         */
        public void sensorUpdateSensorTypeInform(za.org.jcicada.genss.sensor.messages.UpdateSensorTypeInform msg) {
            observer.informSensorType(msg.getSensorURN(), msg.getSensor());
        }

        /**
         * Dispatch TerminateServiceInform.
         */
        public void genssTerminateServiceInform(za.org.jcicada.genss.messages.TerminateServiceInform msg) {
            observer.informTerminateService(msg.getServiceURN());
        }
    }
}
